package com.unlcn.ils.wms.backend.service.sys.impl;


import cn.huiyunche.commons.domain.PageVo;
import cn.huiyunche.commons.exception.BusinessException;
import cn.huiyunche.commons.utils.HttpRequestUtil;
import com.alibaba.fastjson.JSONObject;
import com.unlcn.ils.wms.backend.bo.baseDataBO.WmsWarehouseBO;
import com.unlcn.ils.wms.backend.bo.sys.RoleBO;
import com.unlcn.ils.wms.backend.bo.sys.UserBO;
import com.unlcn.ils.wms.backend.dto.sysDTO.UserNewDTO;
import com.unlcn.ils.wms.backend.enums.DeleteFlagEnum;
import com.unlcn.ils.wms.backend.enums.StatusEnum;
import com.unlcn.ils.wms.backend.enums.UserTypeEnum;
import com.unlcn.ils.wms.backend.service.baseData.WmsWarehouseService;
import com.unlcn.ils.wms.backend.service.sys.PermissionsService;
import com.unlcn.ils.wms.backend.service.sys.RoleService;
import com.unlcn.ils.wms.backend.service.sys.UserService;
import com.unlcn.ils.wms.base.mapper.extmapper.SysUserCustomMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.SysUserExtMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.SysUserRoleCustomMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysUserMapper;
import com.unlcn.ils.wms.base.model.stock.WmsWarehouse;
import com.unlcn.ils.wms.base.model.sys.SysUser;
import com.unlcn.ils.wms.base.model.sys.SysUserExample;
import com.unlcn.ils.wms.base.model.sys.SysUserRole;
import org.apache.axis2.util.ArrayStack;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * Created by houjianhui on 2017/5/11.
 */
@Service("userService")
public class UserServiceImpl implements UserService {

    private Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

    @Value("${erp.bound.host.url}")
    private String propertyUrl;

    @Value("${erp.bound.host.timeout}")
    private String propertyTime;

    @Value("${qr.code.timeout}")
    private String qrTimeout;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysUserCustomMapper userCustomMapper;

    @Autowired
    private SysUserRoleCustomMapper userRoleCustomMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private WmsWarehouseService wmsWarehouseService;

    @Autowired
    private PermissionsService permissionsService;

    @Autowired
    private SysUserExtMapper sysUserExtMapper;

    @Value("${md5.salt}")
    private String salt;

    @Override
    public UserBO isUserExist(String userName) throws Exception {
        UserBO bo = resolvingErpResult("user/isUserExist", userName, null);
//        WarehouseUserBO userBO = warehouseService.getWarehouseByUserId(bo.getIlineid().longValue());
//        if (!Objects.equals(userBO, null)) {
//            bo.setWarehouseid(userBO.getWarehouseId().toString());
//        }
        return bo;
    }

    @Override
    public UserBO getErpUser(String userId) throws Exception {
        return resolvingErpResult("user/getErpUser", null, userId);
    }

    private UserBO resolvingErpResult(String urlParam, String userName, String userId) throws Exception {
        // 构建URL
        String url = propertyUrl + urlParam;
        Integer time = Integer.parseInt(propertyTime);
        if (StringUtils.isNotBlank(userName)) {
            url = url + "?userName=" + userName;
        }
        if (StringUtils.isNotBlank(userId)) {
            url = url + "?id=" + userId;
        }
        String result = HttpRequestUtil.sendHttpGet(url, null, time);
        if (StringUtils.isNotBlank(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            Boolean success = jsonObject.getBoolean("success");
            String message = jsonObject.getString("message");
            String messageCode = jsonObject.getString("messageCode");
            String data = jsonObject.getString("data");
            if (!success) {
                LOGGER.info("user login call erp result messageCode: {}, message: {}", messageCode, message);
                throw new BusinessException(messageCode, message);
            }
            if (StringUtils.isNotBlank(data)) {
                UserBO bo = JSONObject.parseObject(data, UserBO.class);
                return bo;
            }
        }
        return null;
    }

    @Override
    public Integer addUser(UserBO userBO) throws Exception {

        SysUser user = new SysUser();
        BeanUtils.copyProperties(userBO, user);
        validate(user);    //验证数据

        //TODO 没有做用户名校验

        //验证是否传递了 角色信息
        if (userBO.getRoleBOList() == null || userBO.getRoleBOList().isEmpty()) {
            throw new BusinessException("角色不能为空");
        }

        user.setEnable(StatusEnum.RIGHT.getValue());    //设置状态
        user.setGmtCreate(new Date());    //设置创建时间
        user.setGmtModified(new Date());    //设置修改时间
        //新增用户
        userMapper.insert(user);

        Integer userId = user.getId();    //用户id

        //新增用户角色关联
        List<SysUserRole> roleList = new ArrayList<>();
        for (RoleBO roleBO : userBO.getRoleBOList()) {
            SysUserRole userRole = new SysUserRole();
            userRole.setRoleId(roleBO.getId());
            userRole.setUserId(userId);
            roleList.add(userRole);
        }
        userRoleCustomMapper.insertBatch(roleList);
        return userId;
    }

    @Override
    public UserBO findById(Integer id) throws Exception {

        SysUser user = userMapper.selectByPrimaryKey(id);
        if (null != user) {
            UserBO userBO = new UserBO();
            BeanUtils.copyProperties(user, userBO);
            userBO.setPassword(null); //TODO 把密码置空 不返回到页面
            return userBO;
        } else {
            return null;
        }
    }

    @Override
    public UserBO updateUser(UserBO userBO) throws Exception {

        //TODO 暂时 只有 用户名密码 待实现
        return null;
    }

    @Override
    public void deleteUserByIds(String ids) throws Exception {
        userCustomMapper.deleteByIds(Arrays.asList(ids.split(",")), StatusEnum.DELETE.getValue(), new Date());
    }

    @Override
    public List<UserBO> list(UserBO userBO, PageVo pageVo) throws Exception {

        SysUser user = new SysUser();
        BeanUtils.copyProperties(userBO, user);
        user.setEnable(StatusEnum.RIGHT.getValue());
        List<SysUser> list = userCustomMapper.list(user, pageVo);

        List<UserBO> userBOList = new ArrayList<>();
        for (SysUser sysUser : list) {
            UserBO newUserBO = new UserBO();
            BeanUtils.copyProperties(sysUser, newUserBO);
            userBOList.add(newUserBO);
        }

        return userBOList;
    }

    @Override
    public UserBO getLoginInfo(UserBO userBO) throws Exception {

        SysUser user = userCustomMapper.selectByUsername(userBO.getUsername(), StatusEnum.RIGHT.getValue());
        if (null == user) {
            throw new BusinessException("用户不存在");
        }

        UserBO newUserBO = new UserBO();
        BeanUtils.copyProperties(user, newUserBO);
        newUserBO.setPassword(null);    //把密码置空

        //查询用户所属的角色
        List<RoleBO> roleBOList = roleService.findByUserId(user.getId());
        newUserBO.setRoleBOList(roleBOList);

        //调用 isUserExist 接口获取其他的信息
        UserBO otherUserBO = isUserExist(user.getUsername());
        newUserBO.setIlineid(otherUserBO.getIlineid());
        newUserBO.setVcuserno(otherUserBO.getVcuserno());
        newUserBO.setVcusername(otherUserBO.getVcusername());
        newUserBO.setWarehouseid(otherUserBO.getWarehouseid());
        return newUserBO;
    }

    /**
     * app端登录获取权限
     * linbao 2017-09-26
     *
     * @param userBO
     * @return
     * @throws Exception
     */
    @Override
    public RoleBO getPermissForAppLogin(UserBO userBO) throws Exception {

        //校验参数, 并获取对应的仓库
        WmsWarehouse warehouse = checkUserBO(userBO);

        //TODO 获取当前用户 - APP
        SysUser sysUserForApp = getSysUserForApp(userBO);
        if (Objects.equals(sysUserForApp, null)
                || Objects.equals(sysUserForApp.getId(), null)) {
            throw new BusinessException("当前用户不存在");
        }

        List<RoleBO> roleBOList = roleService.findByUserIdAndWarhouseId(sysUserForApp.getId(), warehouse.getWhId());
        if (CollectionUtils.isEmpty(roleBOList)) {
            throw new BusinessException("当前用户没有对应权限");
        }
        RoleBO roleBO = roleBOList.get(0);
        roleBO.setUserId(sysUserForApp.getId());
        roleBO.setUserName(sysUserForApp.getName());
        if (StringUtils.isBlank(qrTimeout) || !StringUtils.isNumeric(qrTimeout)){
            qrTimeout = "0";
        }
        roleBO.setTimeout(qrTimeout);
        return roleBO;
    }

    /**
     * app登录用户获取权限菜单
     *
     * @param userBO
     * @return
     * @throws Exception
     */
    @Override
    public UserNewDTO getPermissListForAppLogin(UserBO userBO) throws Exception {
        //校验参数, 并获取对应的仓库
        WmsWarehouse warehouse = checkUserBO(userBO);

        //TODO 获取当前用户 - APP
        SysUser sysUserForApp = getSysUserForApp(userBO);
        if (Objects.equals(sysUserForApp, null)
                || Objects.equals(sysUserForApp.getId(), null)) {
            throw new BusinessException("当前用户不存在");
        }
        //校验绑定仓库和所选仓库是否一致
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("userName", userBO.getUsername());
        paramMap.put("whCode", userBO.getWhCode());
        Integer countUserWarehouse = sysUserExtMapper.countUserWarehouse(paramMap);
        if (countUserWarehouse <= 0){
            throw new BusinessException("当前登录用户绑定仓库和所选仓库不一致");
        }

        //permissionsService.findPermissionsAndChildByParentIdAndUserId(sysUserForApp.getId(), warehouse.getWhId());
        UserNewDTO userNewDTO = roleService.findByUserIdAndWarhouseIdNew(sysUserForApp.getId(), warehouse.getWhId());
        userNewDTO.setUserId(sysUserForApp.getId());
        userNewDTO.setUserName(sysUserForApp.getName());
        if (StringUtils.isBlank(qrTimeout) || !StringUtils.isNumeric(qrTimeout)){
            qrTimeout = "0";
        }
        userNewDTO.setTimeout(qrTimeout);
        return userNewDTO;
    }

    /**
     * 校验
     *
     * @param userBO
     */
    private WmsWarehouse checkUserBO(UserBO userBO) {
        if (Objects.equals(userBO, null)) {
            throw new BusinessException("参数为空");
        }
        if (StringUtils.isBlank(userBO.getUsername())) {
            throw new BusinessException("用户名不能为空");
        }
        if (StringUtils.isBlank(userBO.getPassword())) {
            throw new BusinessException("密码不能为空");
        }
        if (StringUtils.isBlank(userBO.getWhCode())) {
            throw new BusinessException("请先选择对应的仓库");
        }
        //根据仓库code获取仓库id
        WmsWarehouseBO wmsWarehouseBO = new WmsWarehouseBO();
        wmsWarehouseBO.setWhCode(userBO.getWhCode());
        WmsWarehouse warehouse = wmsWarehouseService.findWarehouseByCode(wmsWarehouseBO);
        if (Objects.equals(warehouse, null) || Objects.equals(warehouse.getWhId(), null)) {
            throw new BusinessException("找不到对应的仓库");
        }
        return warehouse;
    }

    /**
     * 获取登录用户
     *
     * @param userBO
     * @return
     */
    private SysUser getSysUserForApp(UserBO userBO) {

        SysUserExample example = new SysUserExample();
        Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
        List<Byte> typeList = new ArrayStack();
        typeList.add(UserTypeEnum.DELETED.getValue());
        typeList.add(UserTypeEnum.DRIVER.getValue());
        example.createCriteria()
                .andUsernameEqualTo(userBO.getUsername())
                .andPasswordEqualTo(md5PasswordEncoder.encodePassword(userBO.getPassword(), salt))
                .andTypeIn(typeList)
                .andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue())
                .andEnableEqualTo(StatusEnum.RIGHT.getValue());

        List<SysUser> sysUserList = userMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(sysUserList)) {
            throw new BusinessException("当前用户不存在或密码不正确");
        }
        return sysUserList.get(0);
    }

    /**
     * @param @param user
     * @return void    返回类型
     * @throws
     * @Title: validate
     * @Description: 验证用户
     */
    private void validate(SysUser user) {
        if (StringUtils.isBlank(user.getUsername())) {
            throw new BusinessException("用户名不能为空");
        }
        if (StringUtils.isBlank(user.getPassword())) {
            throw new BusinessException("密码不能为空");
        }
    }
}
